﻿// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2022 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

using Furion.DynamicApiController;

using StackExchange.Profiling.Internal;

namespace Abc.Base;

public class AuthorityHelper
{
    /// <summary>
    /// 获取MVC菜单
    /// </summary>
    /// <returns></returns>
    public static List<AuthorityMenuItem> GetMvcPermissions()
    {
        var types = App.Assemblies.SelectMany(o => o.GetTypes().AsEnumerable()
                                           .Where(type => typeof(ControllerBase).IsAssignableFrom(type)));
        //return GetMenus(types, "Admin");

        var AllMenus = new List<AuthorityMenuItem>();

        //遍历所有controller
        foreach (var controller in types)
        {
            //验证Controller是否贴了 AuthorityControllerAttribute
            if (controller.GetCustomAttributes().All(o => o is not AuthorityControllerAttribute)) continue;

            var areaName = "HtAdmin";//默认为HtAdmin
            var controllerName = controller.Name.RemoveLastStr("Controller");// 移除Controller控制器名称
            var controllerDescription = "";//Controller 描述

            var controllerAttribute = controller.GetCustomAttributes().First(o => o is AuthorityControllerAttribute) as AuthorityControllerAttribute;
            if (!string.IsNullOrWhiteSpace(controllerAttribute.Controller))
            {
                controllerName = controllerAttribute.Controller;
            }
            if (!string.IsNullOrWhiteSpace(controllerAttribute.Area))
            {
                areaName = controllerAttribute.Area;
            }
            if (!string.IsNullOrWhiteSpace(controllerAttribute.ControllerDescription))
            {
                controllerDescription = controllerAttribute.ControllerDescription;
            }
            else
            {
                controllerDescription = controllerAttribute.Controller;
            }

            var menus = new List<AuthorityMenuItem>();

            //获取菜单信息
            foreach (var methodInfo in controller.GetMethods())
            {
                //if (methodInfo.GetCustomAttributes().Any(o => o is AuthorityMenuAttribute))
                //{
                //    var menuAttribute = methodInfo.GetCustomAttributes().First(o => o is AuthorityMenuAttribute) as AuthorityMenuAttribute;

                foreach (AuthorityMenuAttribute menuAttribute in methodInfo.GetCustomAttributes().Where(o => o is AuthorityMenuAttribute))
                {
                    var menu = menuAttribute.Adapt<AuthorityMenuItem>();

                    menu.Area = areaName;
                    menu.Controller = controllerName;
                    menu.PCode = controllerAttribute.PCode.Trim();

                    //菜单唯一ID ：area+下划线+controller+下划线+action 名
                    if (string.IsNullOrWhiteSpace(menuAttribute.Code))
                    {
                        menu.Code = $"{areaName}_{controllerName}_{methodInfo.Name}";
                    }
                    else
                    {
                        menu.Code = $"{areaName}_{controllerName}_{menu.Code.Trim()}";
                    }
                    //默认url：Ht
                    if (string.IsNullOrWhiteSpace(menuAttribute.Url))
                    {
                        menu.Url = $"{areaName}/{controllerName}/{methodInfo.Name}";
                        //组装 url 参数
                        if (!string.IsNullOrWhiteSpace(menuAttribute.UrlPar))
                        {
                            menu.Url = $"{menu.Url}?{menuAttribute.UrlPar.TrimStart('?')}";
                        }
                    }
                    menu.MenuArea = MenuArea.Mvc;
                    if (menu.Permissions == null) menu.Permissions = new List<AuthorityPermissionItem>();
                    menu.MenuType = MenuType.菜单;
                    menus.Add(menu);
                }
            }

            if (!menus.Any()) continue;//没有发现菜单，跳过功能权限扫描
            var permissions = new List<AuthorityPermissionItem>();
            foreach (var methodInfo in controller.GetMethods())
            {
                //获取贴的 权限特性
                foreach (AuthorityPermissionAttribute actionAttribute in methodInfo.GetCustomAttributes().Where(o => o is AuthorityPermissionAttribute))
                {
                    var permissionItem = actionAttribute.Adapt<AuthorityPermissionItem>();
                    permissionItem.Controller = controllerName;
                    if (string.IsNullOrWhiteSpace(actionAttribute.Code))
                    {
                        //页面_Action_功能
                        permissionItem.Code = $"Action_{methodInfo.Name.Trim()}";
                    }
                    if (string.IsNullOrWhiteSpace(actionAttribute.Actions))
                    {
                        permissionItem.Actions = methodInfo.Name;
                    }
                    // permissions.Add(permissionItem);

                    AuthorityMenuItem menu = null;
                    if (menus.Count > 1)
                    {
                        if (!string.IsNullOrWhiteSpace(actionAttribute.MenuCode))
                        {
                            var menucode = $"{areaName}_{controllerName}_{actionAttribute.MenuCode}"; ;
                            menu = menus.FirstOrDefault(o => o.Code.Trim().ToLower() == menucode.Trim().ToLower());
                            if (menu != null)
                            {
                            }
                            else
                            {
                                menu = menus.First();
                            }
                        }
                        else
                        {
                            menu = menus.First();
                        }
                    }
                    else
                    {
                        menu = menus.First();
                    }
                    permissionItem.Code = $"{menu.Code}_{permissionItem.Code}";
                    permissionItem.MenuType = MenuType.功能方法;
                    menu.Permissions.Add(permissionItem);
                }
            }

            AllMenus.AddRange(menus);
        }
        return AllMenus;
    }

    /// <summary>
    /// 获取API菜单
    /// </summary>
    /// <returns></returns>
    public static List<AuthorityMenuItem> GetApiPermissions()
    {
        var types = App.Assemblies.SelectMany(a => a.GetTypes()
                       .Where(t => t.GetInterfaces().Contains(typeof(IDynamicApiController))));
        //return GetItems(types, "Api");
        var menus = new List<AuthorityMenuItem>();

        foreach (var controller in types)
        {
            //验证Controller是否贴了 AuthorityControllerAttribute
            if (controller.GetCustomAttributes().All(o => o is not AuthorityControllerAttribute)) continue;

            var areaName = "Api";//默认为HtAdmin
            var controllerName = controller.Name.RemoveLastStr("Controller").RemoveLastStr("Service");// 移除Controller控制器名称
            var controllerDescription = "";//Controller 描述

            var controllerAttribute = controller.GetCustomAttributes().First(o => o is AuthorityControllerAttribute) as AuthorityControllerAttribute;
            if (!string.IsNullOrWhiteSpace(controllerAttribute.Controller))
            {
                controllerName = controllerAttribute.Controller;
            }
            if (!string.IsNullOrWhiteSpace(controllerAttribute.Area))
            {
                areaName = controllerAttribute.Area;
            }
            if (!string.IsNullOrWhiteSpace(controllerAttribute.ControllerDescription))
            {
                controllerDescription = controllerAttribute.ControllerDescription;
            }
            else
            {
                controllerDescription = controllerAttribute.Controller;
            }

            var menu = new AuthorityMenuItem
            {
                MenuArea = MenuArea.API,
                MenuType = MenuType.目录,
                Area = areaName,
                PCode = areaName,
                Name = controllerDescription,
                Code = $"{areaName}_{controllerName}",
                Controller = controllerName,
                Icon = "layui-icon-link",
                Url = $"{areaName}/{controllerName}"
            };

            if (menu.Permissions == null) menu.Permissions = new List<AuthorityPermissionItem>();

            foreach (var methodInfo in controller.GetMethods())
            {
                //获取贴的 权限特性
                foreach (AuthorityPermissionAttribute actionAttribute in methodInfo.GetCustomAttributes().Where(o => o is AuthorityPermissionAttribute))
                {
                    var permissionItem = actionAttribute.Adapt<AuthorityPermissionItem>();
                    permissionItem.Controller = controllerName;
                    if (string.IsNullOrWhiteSpace(actionAttribute.Code))
                    {
                        permissionItem.Code = $"{areaName}_{controllerName}_{methodInfo.Name}";
                    }
                    if (string.IsNullOrWhiteSpace(actionAttribute.Actions))
                    {
                        permissionItem.Actions = methodInfo.Name;
                    }
                    permissionItem.Url = $"{menu.Url}/{permissionItem.Actions}";
                    permissionItem.MenuType = MenuType.API;
                    menu.Permissions.Add(permissionItem);
                }
            }
            menus.Add(menu);
        }
        return menus;
    }
}